{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np \n",
    "import math \n",
    "import matplotlib.pylab as plt\n",
    "from sklearn.metrics import mean_squared_error"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 数据准备部分"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "def shuffle_data(X,y,seed=None):\n",
    "    \"将X和y的数据进行随机排序/乱序化\"\n",
    "    if seed:\n",
    "        np.random.seed(seed)\n",
    "    idx=np.arange(X.shape[0])\n",
    "    print(type(idx))\n",
    "    np.random.shuffle(idx)\n",
    "    return X[idx],y[idx] #对于np.array，idx作为index数组可以改变array的顺序"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[4, 5, 0, 3, 2, 1]"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x=[0,1,2,3,4,5]\n",
    "np.random.shuffle(x)\n",
    "x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 3, 12])"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a=np.array([12,3])\n",
    "a[np.array([1,0])] #翻滚"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'numpy.ndarray'>\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "(array([12,  1,  3]), array([1, 3, 2]))"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "shuffle_data(np.array([12,3,1]), np.array([1,2,3]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "def train_test_split(X,y,test_size=0.5,shuffle=True,seed=None):\n",
    "    '将数据集根据test_size分成训练集和测试集，可以指定是否随机洗牌'\n",
    "    if shuffle:\n",
    "        X,y=shuffle_data(X,y,seed)\n",
    "    split_i=len(y)-int(len(y)//(1/test_size)) #//号保留它的int值\n",
    "    #split_i=len(y)-int(len(y)*test_size)\n",
    "    #分割点确定X，y都确定\n",
    "    X_train,X_test=X[:split_i],X[split_i:]\n",
    "    y_train,y_test=y[:split_i],y[split_i:]\n",
    "    \n",
    "    return X_train, X_test, y_train, y_test"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.datasets import make_regression"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "#make_regression的数据\n",
    "X,y=make_regression(n_samples=100,n_features=1,noise=20)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'numpy.ndarray'>\n"
     ]
    }
   ],
   "source": [
    "X_train,X_test,y_train,y_test=train_test_split(X,y,test_size=0.2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`注意`：因为使用train_test_split函数使得X乱序，在matplot绘制图像时会有问题，所以对于X进行排序\n",
    "\n",
    "乱序花plot时，不是从小到大来画，折线，到处都是一个点\n",
    "\n",
    "评测集做排序"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<matplotlib.lines.Line2D at 0x11e980f98>]"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYEAAAD4CAYAAAAKA1qZAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy8QZhcZAAAgAElEQVR4nOzdd3hUZfbA8e+kF9JDekI6IYVQEnoPRYogKFVFQcEOrHX3t3bXhouKXZBmoYqCukrvJSGhk5BGekJ6z2T6/f0xYSAmgYAJAXk/z+MDc+femRuEc2beco5MkiQEQRCEO5NRR9+AIAiC0HFEEhAEQbiDiSQgCIJwBxNJQBAE4Q4mkoAgCMIdzKSjb6A1nJ2dJV9f346+DUEQhNvK8ePHSyVJ6ny1c26LJODr60tCQkJH34YgCMJtRSaTZV/rHDEcJAiCcAcTSUAQBOEOJpKAIAjCHUwkAUEQhDuYSAKCIAh3MJEEBEEQ7mAiCQiCINzBRBIQBEHoYJIkcSitlCMXSm/6e98Wm8UEQRD+rk7kVPD+H8nEZZYzspsrAwKcb+r7iyQgCILQAdKKavhgewo7kooAmBHtzat3h970+xBJQBAE4SbKr6zno52p/HQiD50EdpamvDclgrER7h1yPyIJCIIg3ATldSo+35vOd0ezUWl1APT3d+LD6ZG421l22H2JJCAIgtCO6pQaVhzKZNmBDGqVGgBMjGQ8N7or84f4Y2wk69D7a5MkIJPJVgITgGJJksIbjjkCGwBfIAuYJklShUwmkwFLgXGAHHhYkqQTbXEfgiAItwqVRsfauGw+25tOaa3KcNzXyYqlM3oS6W3fgXd3WVstEV0N3PWnY/8EdkuSFATsbngMMBYIavhvPvBlG92DIAhCh9PqJH4+mceIJft4/dckzIyNDJ/2p0V58b8Fg1uVAM5frGbGsqO8tvVcu95vm3wTkCTpgEwm8/3T4UnAsIbfrwH2AS81HP9WkiQJiJXJZPYymcxdkqSLbXEvgiAIHUGSJPYkF/PB9hSSC2sI87Cll48Du88XYW1mzLtTujO++7Unf2uVGj7emcqqI1lodVK7f2NozzkB1ysCeyHg2vB7TyD3ivPyGo41SgIymWw++m8K+Pj4tONtCoIg/DUJWeW8vy2Z+KwKfJ2seHtyOEfSy/jldAF9/Rz5aHoPPOyvPvkrSRLbzhXyxq9JFFYrsDE3Qa7WMru/b7ve+02ZGJYkSZLJZNJ1XrMMWAYQFRV1XdcKgiDcDMmF1fx3ewq7zhfT2cac/9wTjr+zNS/8eIbCagUvjOnK40MDrjn5m1Mm57VfzrE3pYRu7rYsmRbJkz+cYEyYK57XSB5/VXsmgaJLwzwymcwdKG44ng94X3GeV8MxQRCE20JuuZyPdqby86l8Opmb8OJdXXmgXxeWH8jg1a3n8Ha0YvMTA+hxjaEcpUbL8gMZfLonHRMjGS+P78bDA3zZkJBLVb2aOQP92v1nac8k8AvwEPBew69brzj+tEwmWw/0BarEfIAgCLeD0loln+1J54e4bIxkMuYP8eeJoQFU1auZveIYp3Irua+3F69PDKOTedPwWlilYPWRLAYEOGFiLOPlLefIKKljXIQbr0wIxd3OEkmSWH04i3BPW6K6OLT7z9RWS0TXoZ8EdpbJZHnAa+iD/0aZTPYIkA1Mazj9d/TLQ9PRLxGd0xb3IAiC0F5qFGqWH8zkm4MZKDU6pkV5szAmCFdbc346kc+rW89hZCTj05k9uTvSo8n1JTVKvtx3ge/jslFpdHy1/wIAPo5WrJoTzfCuLoZzD6WXklZcy5KpkehX1LevtlodNLOFp2KaOVcCnmqL9xUEQWhPSo2W72Nz+HxvOuV1KsZHuPPs6GACOneiWqFm4fpT/HK6gD6+jnw4PRIvB6tG11fUqfj6QAZrjmRRr9Yajpsay3h8aABPDQ/EwtS40TWrDmfh3MmcCZE3p4yE2DEsCILwJ/q1/vl8tDOV/Mp6BgU688KYroblmglZ5Sxcf4rCagXPjQrmyeGBjSZ/q+rVrDiYwcrDWYZdwpcMCHDirXvCCejcqcn7ZpbWsSe5mIUxQZibGDd5vj2IJCAIgtBAkiR2JhXxwfYU0opr6e5lx/v3dmdQkL68s0ar45M96Xy2Jw1PB0s2Pd6fXj6Xx+1rlRpWH9aXiKhWaOjr50hcZrnh+aUzejAx0qPFYZ41R7IwNZZxf7+btyxeJAFBEAQgLqOM97clcyKnEn9na764vxdjw90MATu3XM7C9Sc5kVPJlJ6evDEpDBsLUwDqVVq+i83iq/0ZlNepGNnNhS5O1qw4lGl4/dOvjcbO0rTF969WqNmUkMvdkR642Fi07w97BZEEBEG4oyUVVLN4ezL7UkpwtTXn3SkRTO3thYnx5ao6P5/M45UticjQf5qf1MMTAIVay7pjOXyx7wIlNUoGBzlzby8v1sblGBLAtCgvFt8Xec372BifS51Ky9ybsCz0SiIJCIJwR8ouq+PDnalsPVWAnaUp/xobwkMDfBtN1FYr1Ly65RxbThUQ1cWBj6b3wNvRCpVGx6bjuXy2J52LVQr9ruBpPYjPKmfRhlOG69+ZHMGsvtce2tHqJNYczSLa14FwT7v2+HFbJJKAIAh3lOIaBZ/uTmfdsRxMjGU8OSyAx4YGNBmqOZ6tn/wtqKxn0cggnh4eCMCmhFyW7k4jr6KeXj72/HdqJFqdxMtbzpJVJjdc/9+pkdzX26tV97T7fBG55fX8a2y3tvtBW0kkAUEQ7gjVCjXL9mew4lAmaq2OGX28WTAiCBfbxuPvGq2Oz/am8+medNztLNj0eH96eDvw25kClu5KI6O0jghPO966J5xQd1ve/C2J/525SGcbcwCMZPDR9MtDRq2x6nAWnvaWjA51vfbJbUwkAUEQ/tYUai3fHc3m833pVMrV3B3pwXOjgvF1tm5ybm65nH9sOEVCdgX39PDgjUnhHEkvZezSA6QW1RLiZsPXD/YmJsSF72KzeWbtSVRaHY8O8uNoRhnldSo+mdGzVdVCLzl/sZqjGWX8c2xIo3mIm0UkAUEQ/pY0Wh2bT+Tx8a40LlYpGBLcmRfHdG1xzH3rqXxe/vkcEvDR9EhszE2ZuSyWpIvVBHS25tOZPRkf4c6Z/ComfX6YxIJqhgR35rlRwbyy9RypRTV8PqsXd4W7Xdd9rj6chYWpETOiva99cjsQSUAQhL8VSZLYnljIB9tTuFBSRw9ve5ZMi2RAgHOz59co1Ly2NZGfTubTy8eee3t7sfpINqdzK/FxtOLDaZFM6uFJrULDK1vPsfZYDi425nw+qxf9A5x44Js40otr+eqB3sR0u77hnPI6FVtO5XNvby/srcza4se/biIJCILwt3HkQinvb0vhdG4lgS6d+OqB3owJc21xc9aJnAoWrT9FXoWcvn6OqLU6/v3zOTztLXlvSgT39vbCxEjGllP5vP2/85TXqXh4gC/PjgpGqdExa3ksGaV1LJvdm2FX1P9prXXHclBqdMwZ4PsXf/IbJ5KAIAi3vXP5Vby/LZmDaaV42Fmw+L7uTOnp2eIYu1Yn8fnedJbuTkOrkzA3MSIusxwXG3PenBTG9GhvzE2MSS+u5ZUt5ziaUUYPb3tWz+lDuKcdxTUK7l8eR26FnJUPRRt2FF8PtVbHd0ezGRzkTJCrzV/9I7hhIgkIgnDbyiytY8mOFH47cxF7K1NeHt+NB/p1aVKU7Up5FfrJ3/isCsOxTuYmvDAmwHBtvUrLB9uTWXYgA0tTY96eHM7MaB+MjGQUVimYtTyWwmoFq+f0oZ+/0w3d+x/nCimsVvDOlPAbur6tiCQgCMJtp6hawdLdaWyIz8XM2IhnRgQyb4g/thYtl2UA+OV0AQvWnTQ8trM05bGh/jzU3xfrhvr/e5KLeHVrInkV9Uzp5cn/jeuGcyf98s/8ynpmLY+lrFbFt3P7EOXreMM/w6rDmfg5WzMw0Jlt5wpJKqhi4cjga3Yha2siCQiCcNuokqv56sAFVh3ORKuTeKCvD0+PCDKs0W9JrVLDgyviOJlTaTi2aGQQcwf5GRJHQWU9b/6axLbEQgJdOrFuXj/6B1z+lJ9bLmfm8liq6tV8+0ifRoXjrtfJnApO5lRiYWrEwPf2UFqrwsvBkvlDA5ptRtOeRBIQBOGWV6/SsuZoFl/uu0C1Qs2kSA+eHdUVHyera1679VQ+C9dfLuXw2BB/nhgWYFiNo9bqWH04i492paKTJF4Y05V5g/0xM7k8n5BdVsfMZbHUqbT88GhfuntdvW1kSxRqLX+cu8g/NpxueKzD3tKINybq5yGuNozVXkQSEAThlqXR6tiYkMfS3akUVSsZ3rUzL4wJIdTD9prX5pbLGbx4r+FxpLc9Kx+KwqnT5W8Nx7PL+ffP50gurCEmxIXXJ4bh7dg4sWSU1DJzeSwqjY4fHu17Q7V9kgqq2RCfw88n86lWXO4v8NakMKZGdUzwv0QkAUEQbjk6ncQf5wpZsiOFjNI6endx4JMZPenbiknYomoF//75HLvOFxmO7Xp2CIEul1fgVNSpeO+PZDYk5OJuZ8HXD/ZmdGjTpaTpxTXMXB6HTiexbn4/QtyunXwuqVGo+fX0RdbH53Amr6rJ83++p44ikoAgCLeUg2klLN6Wwtn8KoJdO/HN7Chiurlcs99uaa2Sr/Zd4Jsravg/NyqYp0cEGq7V6SR+PJHHu7+fp1qhYf4QfxbGBBkmha+UXFjN/cvjMDKSsX5+v1Yt45QkiRM5lWyIz+HX0xcbtZT0tLfkkUF+fLQzlX4BTrdEAgCRBARBuEWczq1k8fZkDqeX4WlvyZKpkdzT0/Oaq2Uq5fo+vl/uu2A45mhtxk9PDGhUHyilsIaXt5wlPquCqC4O/GdyeIuf7BMLqnjgmzjMTYxZO68v/s20grxSeZ2Kn0/msyE+h9Si2kbPedpb8tTwQO7r7cWWk/nUKDXMGeh7jT+Nm0ckAUEQOtSFklqW7Ejh97OFOFqb8eqEUO7v53PNHrvVCjUrDmay4lBmoz6+Tw0PYNHIYEwbNorJVRqW7kpjxaFMbCxMWHxvd+7r7YVRC8nlTF4lD644hrWZMevm96OLU9NCc6D/VnE0o4x1x3LYkViESqtr9LyXgyVPDw9kSi8vzEyMkCSJlYczCXGzof8N7i1oDyIJCILQIS5W1bN0VxqbjudhYWLEopFBPDrY/5pLJOuUGlYfyWLZgQyq6tWG4+52Fnw0vUejzVs7Egt5/ZdECqoUTI/y5qWxIThat1yj50ROBQ+tOIadlSnr5vVrMkkM+jmHTQm5bEjIJbe8HjtLU9zsLCisVqDS6PB2vBz8Ta/YsRybUU5yYQ3v3xtxzaGtm0kkAUEQbqpKuYov911g9ZEsJAlm9+/CU8MDDRuyWlKv0vJ9bDZf7r9AeZ2KUHdbdJJEjULD+Ah33pkcgZ2Vfs1/brmcN35NZNf5Yrq62vDjzJ7X3NiVkFXOw6vicepkxtp5/fC0tzQ8p9Hq2JtSwob4HPYkF6OToL+/Ez28HUi+WE1acS0+jlY8PSKQyT09GwX/S1YdzsTByvS6+gzcDCIJCIJwU8hVGlYdzuKr/ReoVWqY0tOLRSODmv20fSWlRsu6uBw+v6KPb6i7Levjc9HqJBbf152pvb2QyWSoNDq+OZTBJ7vTMJLJ+L9xIcwZ6NdsUL5SbEYZc1fH42Zrwdp5/XCz0zeayS6rY2NCLpsS8iiuUeJiY85jQwNwsDJly8kCjmaU0cXJig/u6849LQR/0CelneeLeHJYQIcuB22OSAKCILQrtVbH+vhcPtmdRkmNkpHdXHlhTFe6ul19dYxaq2NTQh6f7UmjoEpBHz9HFt/XnW1nC/n6QAbdvexYOqMnfg2Tv7EZZbyy5RxpxbWMCXPltbvD8Lji03xLDqeX8siaeLwdrPhhXl9sLUz55XQBG+JzOJxehpEMRoS4MDXKG7VWx2d70kkurMHXyYolUyOZ1MPjms1g1hzJwlgm48F+vq3+c7tZRBIQBKFd6HQSv529yJIdKWSXyYn2deDL+3tdc1hGo9Wx5VQBS3enklteT08fexbfF4mdpSkL158ks6yOJ4YF8I+RwZiZGFFaq+Sd38/z04l8vBwsWfFQVKvr+u9LKeax747j52zNq3eH8tW+DH46mUelXI23oyXPjw5mSi8vTuVW8tHOVJILa/B3tubDaZFMjLx28Ad9yYoNCbmMjXA3fMO4lYgkIAhCm5Ikif2p+rX+SRerCXGzYdXD0Qzr2vmqE6I6ncSvV/TxDfOwZeXDYQwNdmH5wQyW7EjBydqcHx7ty4AAZ3Q6ibVxOby/LRm5SsOTwwJ4ZkQQlmatG27Zfb6IR9YkADT0BojDzNiI0WGuzIj2oZ+/I9sTi5izKp6Uohr8O1vz8fQe3B3pcV1F3jYfz6NGcWstC72SSAKCILSZEzkVvP9HMnGZ5Xg7WvLx9B5MjPRocTkmXO4E9tHONFKKaujqamNoBnOhpI77v4klNqOcseFuvDslAnsrMxILqnh5yzlO5lTS18+RtyeHt3rzlSRJfLA9hS+u2FdgbCTj5fHdmNLLCztLU34/e5FxnxwktaiWgM7WLJ3Rgwndry/4gz6xrT6SRaS3/V8qONeeRBIQBOEvSyuq4YPtKexIKsK5kxlvTAxjZh+fRkXY/kySJPamFLNkRyqJBdX4d7bmk5k9mRDhTmxmGX7/+r3R+SlF+hIO5y9WG46FuNlwb28vssvkVCs0OFqZ4WBlho2FSZPEUyVXs+VUPq/9kmg4dleYG/OG+NHLxwGdBP87e5FPdqeRXlxLoEsnPmnoK3yj5Z33p5aQWVrH0hk9buj6m0EkAUEQblh+ZT0f70xl84k8rMxMeG5UMHMH+TVbhuESSZI4lF7Kkh2pnMqtxNvRkv9OjeSeHh7EZ1VwzxeHG9XaGR/hjr2VKWuP5SBJjV8rubCGF3880+Q9jI1kOFiZYm9lRnpxbZPnAd6dEkE3d1tsLUz4Pi6H1YczuVBSR5BLJz6d2ZNxfyH4X7LycCYuNuaMDXf/S6/TnkQSEIS/ObVWd80lktervE7F53vT+e5oNshg7kA/nhweeNWNWABxGWUs2ZnKscxyPOwseHdKBPf19uJ4dgUPrIgjNqPccO7DA3z5v3HduFhVz6tbE5EkCHW35e3J4fT0cUCSJGqVGirlasrrVJTLVVTUqSivU5FeXMv6+FxKa1Ut3su/fjrb4nM/xGXz+9mLOFib6b9dWJvhaG2KQ8M3DUdr/TFrM+MW5znSi2s4mFbKc6OCr/qNqKOJJCAIf2M7Egt5eu1JZvbR75a1Mvtr/+TrlBpWHMpk2YEM5CoN9/X2YuHI4EYbqy5RqLXEZpQxrKsLJ3Iq+HBHKofSS3GxMeeNiWHM6OPNqZxKZq84xtGMMsN19lamfDGrF719Hfhq/wU+35uOqbERr04IZXb/LoYVOTKZDBsLU2wsTPF2tEKrkziQWsL2xEJ2ny8GoI+fIzP7eFMlV/PGb0kMCHDig/si2RCfy9LdaYb37OVjTx8/J6rq9Umkok5NenEtFXIVFXI1Wt2fvoI0MDM2wqFJcjDF0cqMk7mVmJkYMauvz1/6M29v7Z4EZDJZFlADaAGNJElRMpnMEdgA+AJZwDRJkipaeg1BEK5fXoWc5zedxt7KlDVHs9mfWsJ/p0beUEtElUbHumM5fLonjdJaFWPCXHl+dNcWK2uezavi2Y2nSCuuJdi1E6lFtThamxl6AJ/Jq2LOqniOXChrdN2YMFfem9KdpIvVjP34IBmldYzv7s4r40NbXF6ZVyFnY0IemxJyuVilwLmTGY8M9mN6lDf+nTvxXWw2r/+axKBAZ8ZGuDFreSxZZXJC3GxYNDKI0aFuV5241un0u5LL5foEUdnwa4VcRXmdmoqG31fIVSQXVlMhV1MhVyFJcH9fn0b9C25FMunPg2xt/Qb6JBAlSVLpFccWA+WSJL0nk8n+CThIkvRSS68RFRUlJSQktOt9CsLfiVqrY/rXR0ktquV/CwZRUKnghR9Pk19Zz7zB/jw7KrhVO1d1Oomtp/P5cKd+zX4/f0devCukxZUuaq2Oz/em8/Guy5+y7SxNmT/En4cH+JJ0sZqPd6VyOL0M507mBLpYczq3CgmJVyeEMTLUhbf/d56tpwro4mTFm5PCGRrcucn7qDQ6dp0vYt2xHA6l60PL0ODOzIj2ZkSIq2H4ZdXhTN74NQnQ1xa6WKUg1N2WBTFBjA51vWrw/yu0OokahRpbC9N2e4/WkMlkxyVJirraOR01HDQJGNbw+zXAPqDFJCAIwvX5cGcqJ3Iq+WRmT7o4WdPFyZpti4bwzu/nWXYggz3JxSyZGkmkd/NtEi+t3Fm8LYXkwhrCPGxZMzeCIUHOLY6BpxXVMPmLI40qei6MCeKRwX6kFtbw2HfHOZReinMnc54fHUxGaR0/ncgnzMOWj6f34GhGGTFL9qNU61gQE9RsiYX04lo2JuSy+XgeZXUqPOwsWBgTxNQo7yZDUl/sS2fxthTDY0dr/aqlUc00j2lrxkYyQ/vKW93N+CaQCVQAEvC1JEnLZDJZpSRJ9g3Py4CKS4+vuG4+MB/Ax8end3Z2drvepyD8XexPLeGhlceY2ceHd6dENHn+QGoJL20+Q3GNkieGBrAgJqjRxGVCVjnvb0smPqsCXycrnhvdlfER7i1+otXpJF7/NZFvj17+N/rksADmD/HnQkktH+9K42BaKc6dzHh8aAA9fex5afNZ0otrmT/EnzFhrrzxaxJn8qoYFOjMm5PCGtXvr1dp+f2svkNXfFYFJkYyRoW6Mj3am8FBnZus4FFrdYz8cD/ZZXJAv4z0+dFdW9WY5u+mNd8EbkYS8JQkKV8mk7kAO4FngF+uDPoymaxCkqQWd1KI4SBBaJ2iagXjlh7EuZM5W58e2OKQT1W9mjd/TWLziTy6uduyZGokRkbw3+0p7DpfTGcbcxbGBDE92vuqK4tiM8qYsSzW8PieHh68PCGU7DI5H+9K5WBaKU7W+uA/q68P647lsHhbCvZWprw+MYzYjDK+i83GuZM5r0wI5e7u7oZAfS6/ivXxOWw9WUCNUoO/szXTo72Z0suLzjZNx9lVGh2bT+Q1WvXTUtvIO8UtMRwkSVJ+w6/FMpnsZ6APUCSTydwlSbook8ncgeL2vg9B+LvT6iQWrT+FXKXls1k9rzrmb2dpypJpkdwV7sa8bxMY98lBAKzMjHlhTFfmDPS96kqiomoFgxfvRaXRN1KxNjNmz/PDyK+s59mNpzmQWoKTtRn/Ny6EB/p1oVah4fHvj3MwrZSR3VwZFOjEa78kUlarZHa/Ljw3piu2FqZUK9RsPaUv3nYuvxpzEyPGR7gzPdqbPn6OzQZzlUbHj8fz+HxvOvmV9QA4WZsR938xrartc6dr1yQgk8msASNJkmoafj8aeBP4BXgIeK/h163teR+CcCf4bE86RzPKWHxf91b1wy2tVXI4vbTRsc425owOdW0xAZTVKnnj1yR+OV1gOLbp8f4YG8l48ccz7E8twdHajH+NDeHB/l2wMjNhV1IRL24+g1yl4ZFBfiQXVvP6r0l097Jj5UPRhHvacjy7gnXHcvnf2QIUah3d3G15c1IYk3p4Ymdp2uy9KDVaNiXk8eW+C4bgDzAj2pt3Jkd06ITs7aS9vwm4Aj83ZG8TYK0kSdtkMlk8sFEmkz0CZAPT2vk+BOFvLTajjKW7U5nc05Opvb2uem6NQs03BzP55mAGCo2OmX28WRATxInsSl7ecpbxnx7i+dHBPDLI3zDeXilXsexARqN6O3MH+jEh0p2lu9IMwf+fY0N4sF8XrM1NUKi1vLLlHN/FZuPf2Zp+/o58dzQbc1Mj3poUxl3h7mw5mc+iDSe5UFJHJ3MTpvTyYma0D+Geti0O4Sg1WjYm5PHl3nQKqhT08LbH0syY9OJaHuzXhTcmhokEcB3afU6gLYg5AUFoWVmtknGfHMTKzIRfnxnUYntGpUbLD7E5fLY3nfI6FeMj3Hl2dDABV0zCltQo+ffPZ9mRVETvLg68fncYu5OLGi35tLUw4c1J4Ww5lc++lBIcrEyZPySA2f27GMpFnL9YzYJ1J0krriXIpRO1Sg0XqxRMjPRgaHBn9iQXsyOpELVWoncXB6ZHezOhu/tVh6AUai0bE3L5ct8FLlYp6N3FgQUxQexKKuK72GzmDPTl1Qmhd+z4f3NuiYnhtiCSgCA0T6eTmLtGv+nq5ycHEOZh1+QcrU7i55P5fLQzlfzKegYGOvHimJCrLg9deyyHf/98rslzd4W5IVdrOZBagr2Vfv3/7P6+hsSj00msOpLF+38ko9LqsLEwoUahwdLUmO5eduRV1JNfWY+DlSlTenkxI9r7mkNXCrWWDfH64F9YrSCqiwOLRgYzIMCJf285y7pjucwf4s+/xoaIBPAnt8TEsCAI7eebQxnsSynhrUlhTRKAJEnsOl/MB9uTSS2qJcLTjvfv7c6gIOcWX0+hbujje8Wwz5W2JRZib2XKC2O68tAA30bfOoprFDy/6QwHUksMx2oU+j0D9WotcZnlDAp05l/jQhgV6oq5ydU3qynUWtYdy+Gr/RcoqlbSx9eRJdMiGRDghE6CFzef4cfjeTw1PIDnR3cVCeAGiSQgCLepEzkVLN6WwthwNx7o16XRc3EZZby/LZkTOZX4O1vzxf29GBvudtVx9g3xuXy2J53iGiUtDal7OVjyx8LB2Fg0nqzdk1zEC5vOUFbXtGCbq60506K8mRblfc1+wqAP/mvj9MG/uEZJHz9HPpreg/7+TshkMjRaHc9vOs2WUwUsGhnEwpggkQD+ApEEBOE2VCVX88zak7jZWfDevd0NQTCpoJrF25PZl1KCq605706JYGpvrxaXSqq1OjYfz+PTPfrllRGedjh1Mm9Us9/O0pRxEW4kFlRzJq+Kp9ee5L17I6ioU/PHuYuU1alYG5fT5LVHdnNlZh9vhgZ3btVSzXqVlh/isvn6QAYlNUr6+TuydEZP+gc4Nbrff2w4xW9nLvLCmK48NTzwev/ohD8RSUAQbjOSJPHS5jMUVSvY9Hh/7CxNySmTs2RnCr+cLsDG3GGsY5EAACAASURBVIR/jg3h4QG+Le4V0OoktpzMZ+nuNHLK5UR62zMj2pslO1MN55iZGPHM8EAeHuiLjYUpOp3E93HZvP5LIv3f3dPi/T05LICHBvjiatu6frqXgv9X+zMorVXS39+JT2f2pJ+/U6PzVBodC9adZFtiIf83LoT5QwJa9frC1YkkIAi3me9jsw2B0NPBkle3nmNtXA4mxjKeGBrAY0MCsLNqfm39pebvH+9KJaNE38f3qwd6sSE+t1ECeHZUMA8P9MX2imEfIyMZXV1taKGqMi+P78bcgX6tXp4pV2n4PjabZQcyKK1VMTDQiS9ietHHr2mVU6VGy1M/nGDX+WJenRDK3EF+rXoP4dpEEhCE20hiQRVv/XaeqC4OVNWrGbp4HyqtjhnR+rX+LX361vfxLeLjXakkF9YQ7NqJrx7oRZ1Sy+PfnzCcN2+wH8/EBDUK/gDVCjUzvo4l6YphoktevKsrjw8JuK7g/91RffAvq1MxKNCZhSODiG6hxLVCreWx746zP1U/Af5gf99WvY/QOiIJCMJtolapYf63x1FpdSRkV5CQXcHdkR48OyoYP2frZq+RJIl9KSUs2ZnCufxq/J31TdP9nK2Z+Nlhw3kRnnZ8/2jfJrtzK+UqnvzhRJO6/5dsWzSYEDfbVt1/nVLDt0ezWX4wg/I6FYODnFk0MojeXVrub1Cv0jLv2wQOXyjlvSkRzOhzazdouR2JJCAItwGNVkf4a9sNj4cEd+bFMV0J92y6LwD0wf9wehlLdqZwMkffx/eD+7rTzd2W5zedJrmwxnDuvueH4XtFEtHpJGIzyvhsb3qLwR/g4IvDW7Xap1ap4dujWSw/kEGFXM2Q4M4sjAmid5cWa0YC+qTxyJp44jLL+eC+SO67xk5o4caIJCAItzD9ME5hoyGbtfP6MiCg5bX+xzLLWbIjhbjMctztLHhncgQRnnZ8tjeNF65oyv7WpDAe6NfFsLKouFrBpuN5bIjPJadcftX72r5oyDUTQI1CbfjkXylXM6xrZxbEBLXYkOZKtUoNc1Yd43h2BR9P78GkHp7XvEa4MSIJCMIt6siFUt7flsLp3ErDsfS3x7a43PJkTgUf7tSXb+5sY87rd4fSq4u+T+///Xy5vHIPb3u+eqA3bnYWaLQ69qcWs+5YLntTilvspXuln54cQFe3lnf51ijUrDmSxTeHMqmUqxnetTMLRwbTo4Udyn9WrVDz0MpjnMmr4pOZPZnQ3aNV1wk3RiQBQbjFnMuv4v1tyRxMK8WhYZWPvZUpOxYNaTYBnMuv4qOdqexOLsaxoXxzHz8nlh/I4PWG1oqXvDM5gpl9vMmrqOe/21PYdDyXomoljtZmGMn0jcCv5rtH+rT4Sb5aoWb14SxWHMqkql5NTIgLC2KCWixP0ZwquZoHV8Zx/mI1n8/qxV3hbq2+VrgxIgkIwi0iq7SO/+5I4bczF7G3MuXl8d1IuljNTyfyWTqjJy5/WvmTWlTDRztT+eNcIbYWJrwwpisDApz45lAm7/6RzJVlwfr4OvLOlAjOX6zmwRXHOJReipEMhnV1YVYfe7YnFlL+p92+ZiZG9PN3MpSB+HxWLwYHNe33W1V/KfhnUK3QMLKbPvh392p98AeoqFNx/zdxpBfX8uX9vRkZ6npd1ws3RiQBQehgRdUKPtmdxob4XEyNjXhmRCDzhvizP6WE//zvPE8MC2jUbD2joWXjr2cKsDYzYUFMEEODnVl1OIv/7kjBytQYf2drMkvrMDE2YnIPT6zMjZn61REq5Go87S15dlQwEyM92JCQy0e7Upvc09IZPUgvruXTPekAvDslgvHd3RudU1WvZuWhTFYezqRGoWFUqCsLY4JanKy+mtJaJQ98E0dGaR3LZvdmWFeX634N4caIJCAIHaSqXs1X+y+w6nAmGq3ErL4+PD0iEBcbC7LL6vjXT2fp5WPPs6OCAcgtl7N0dxo/ncjD3MSYx4YEENPNhW+PZvPpnjSsTI25v68PeRX17EvRf3o3NzFiQ0IupsYyRoe6MT3am/4BTny57wLD/ruvyT0NCnTmm4ei2Hau0JAAXrorhJlXLM2skqtZcTiTVQ3Bf3SoKwtuMPiDvvDc/cvjyK2Qs/Kh6KsWuBPankgCgnCTKdRaVh/J4st9F6hWqJkU6cGzo7ri46RfbaPUaHl67UmMjWR8MrMnJTVKPtubzsb4XIyMZMwZ6MeoUFfWxuUw7eujWJoa88TQALq62bBw/alG7+ViY86CEUFM6uFBWnEtG+Jzmb3yWJN7ujvSgzcnhuFgbUZCVjmLNuhfZ+5AP54Ypi/PUClXseJQJqsPZ1Gj1HBXmBvPxAQ2W766tQqrFMxaHkthtYJVD/dpVCdIuDlEEhCEm0Sj1bHpeB4f70qlqFrJ8K6deWFMCKEejTdbvfdHMmfzq/jPPeF8czCTtXE5SEjM7OPD2HA3NiTkMnN5LJamxjw+NIC7u3sYegRfcm8vL+7t7YlaK/HH2YuM+fgAFXJ1k3sKcbPh7cnhhg1bOWVy7vvqKKDvHfDKhG5U1DUE/yNZ1Co1jA13Y0FMEN3cW7dJrCX5lfXMWh5LaY2SNXP7tLhjWGhfoqmMILQzSZL4/WwhS3akkFFaRy8fe166K4S+/k0/9e5MKmLet/q/6xamRqi1Evf18mJ8d3d+OpHHL6cLsDA15sH+XejhZc87f5wnt/xyf92X7tLXEzqYWsKOpCKq6psGftA3lH92VDAPD/A1rDiqqlcT+cYOQJ8cvn+0LysPZbLmSBZ1Ki3jI9x5Jiaw1TuErya3XM7M5bFUydWsucqKI+GvEU1lBKGDHUor5f1t+k/2wa6dWD47ipHdXJqtf59UUG1IAADjwt25O9KDX04X8PCqY5ibGDO5pxdOncz47fRFvt6fYTh3UKAzrrYWfLkvnWqFBhtzE2K6uVCv1nIgtZR69eXFn2PD3Xj17lDc7SwNx9RanSEBAAwMdGbo4r3I1VrGRbizYETQVfcGXI/ssjpmLY+jRqHmh3l9r3sVkdC2RBIQhHZwJq+S97clczi9DE97S5ZMjeSenp6Gxu1XqlGoWX4gg08aJmLDPW1ZGBPM72cv8siaeEyMjQh2tcHWwpStp/LR/GlDl5EMDqWXYmthwqhQN8ZFuNHFyZo3fk3kYFqp4TxvR0venBjO8JDGK28kSeKujw80OrbycCYTunvwzIhAgq/R/vF6ZJTUMmt5HEqNlrXz+t3wZLLQdkQSEIQ2dKGkliU7Uvj9bCGO1ma8OiGU+/v5NNtKUa7SsOZINl8fuEBlw3j9uAg3LEyMeey7hEYlm5MLazAzMWqSAOytTBkd6srYCHcGBjhjbCRj1eFMnvzhBEqNDgBjI32J6aeGB2Jp1vQ+HloVz4WSOsPjiZH64H+t3r/XK724hpnL49DpJNbO6/eX5xSEtiGSgCC0gYtV9XyyO42NCXlYmBixMCaIRwf7NWnDCJf7+H61/wKltSpMrvh28PvZwibnqxqC+aVfQT+kM7OPD/0DnDBtGNM/f7Gaf24+w+m8KsN5/f2deOuecAJdOjV53ZIaJdFv7zI87uvnyNuTI5o9969KLqzm/uVxyGQy1s/v1+YJRrhxIgkIwl9QKVfx5b4LrD6ShU6SmN2/C08ND8S5k3mTc5UaLRvjc/lsbzpF1UoGBDgxb3Bn3v0judXvN6uvD29ODGtUPkKh1vL53nTDun4A505mvDw+lEk9PJrMPxTXKFi2P4NvDmUajn0+q1eTzWBtJbGgige+icPMxIi18/oR0Lntk4xw40QSEIQbIFdpWHU4i6/2X6BWqWFyT0/+MTK42cqaaq2On07k8clufR/faF8Hnh0VzIHU0lYngOFdO/P+fd1xsWlcOiI+q5yXNp8h44rhnAf6+fDC6JAm3cWKqxV8tT+DH+KyDUNFAKvmRDO8nXbons2r4oEVcVibGbN2Xr9GJauFW4NIAoJwHdRaHRvic1m6O42SGiUju7nwwpiQZlfOaHUSW0/p+/hml8mJ9LLj8WEBrD+Ww0ubzzbz6uBma8Fd4W5UK9T8cbYQYyMZr94dytTeXo0+0dco1CzelsJ3sdmGY+Getvznnogm1TqLqxV8uf8Ca+Ny0Ogk7unhyR/nLiJXaXlzUli7JYCTORXMXnkMWwtT1s/v16reA8LNJ5KAILTCpd68S3akkF0mJ9rXgS/v70VUMxucdDqJ389d5ONdaaQX19LN3ZbnRgWzZGdqo/H6S9ztLBgX4c64CDc87a34109n2JtSQn9/Jz6Y2h0vh8bBc/f5Il788QxlDQXfjGTw6oRQHuzv22j1UWGVgq/2X2DtsRy0OokpPT15anggvs7WPDk8gHqVtt1W5yRklfPwqngcrc1YN78fnvaW175I6BAiCQjCVUiSxIG0UhZvSyaxoJoQNxtWPhzF8K5N1/pLksTOpCI+3Knv4xvo0okxYa5sTyzifDO9eQG+f6QvAwOdkMlk/HK6gLmrE1Cotbx+dyiz+/s26ttbWqvkjV+T+PV0geHYhO7uvDIhtFFv4cIqBV/uS2ddfC5ancS9vfTBv4vT5aGY9hyXj80oY+7qeNxsLVg7rx9uds33PRZuDSIJCEILTuRUsHhbMrEZ5Xg7WvLx9B5MjPRo0lBdkiT2pZbw0c5UzuRVGfr0phfXkl5c2+jcx4b4s/lEPtX1an56cgDhnnZU1Kl4ees5/nfmIj287VkyLbJRkJYkiZ9O5PPcptOGY572lrx3b0Sj0s4FlfV8ue8CG+Jz0UkS9/X24qnhgTd1GOZweimPrInHy8GKtY/2bVL+Wrj1iCQgCH+SXlzD4m0p7EgqwrmTGW9MDGNmHx/MTJo2dDmSXsqSnakcz64wHPtzqYax4W48NTyQMA9bVhzK1H+inxhGuKcde5KLeGnzWSrlKl4Y05XHhvg3WvmTWy7nnz+d4XD65V6/i0YG8fjQACxM9Wv+Cyrr+WJfOhvj89BJElOjvHhy2M0N/gD7U0uY/20Cvk7W/DCvb7MrpIRbj0gCgtAgv7Kej3emsvlEHlZmJjw7KphHBvlhbd70n0l8lr6Pb2xGeYuvt2pONMOCOxuGjU7lVvLeH8mMCXNlSi9PXvzxNBsT8ghxs2HNnD6NCslpdRKrj2Tx1m+XO4MNCnTmrXvC8WtYYZNfWc8Xe9PZmJALwNQob54cFtBkDuFm2H2+iCe+P0GgSye+f7QvjtZmN/0ehBsjkoBwxyuvU/HF3nS+jc0GSV8++cnhgc0GslO5lXywPbnRJ/Mr9fSx54v7ezWqywP6bwfPrDuBq60Fk3t6cdfHB7lYVc8TwwJYNDKo0Y7i5MJqnvzhRKNln5/N6sn4CHdkMhl5FXI+33uBH4/rg/+0KG+eHB7YYZOv2xMLeXrtCULcbPnukT7YW4kEcDsRSUC4Y9UpNaw4lMmyAxnIVRru7eXFolHBzQbTxIIqFq0/RdqfxvgveaCfD08OC8SjmWslSeJfP50ht7yeHt72PP79cXydrNj0eH9DCWfQbyb7fE+6oYYQwMMDfHludDA2Fqbklsv5Yl86mxLyMJLJmBHtwxPDApp9z5vlf2cusnD9ScI97Vgzt49hPkS4fXRYEpDJZHcBSwFj4BtJkt7rqHsR7iwqjY51x3L4dE8apbUqxoS58vzors2WMlCotSw7kMGHO5u2YJTJYFYfn2t+Cv8+LsdQDuJUbiUP9e/CS2NDsDK7/M8vIaucqV8fNfQF9nG04ov7exHuaUdOmZz//HaezSf0wX9WX33w//O3jZtt66l8/rHhFL18HFg1J7rZEhnCra9DkoBMJjMGPgdGAXlAvEwm+0WSpKSrXykIN06nk/jldAFLdqaQW15PXz9Hls0OabaWfUphDevjc/j5ZL6huNslpsYypkZ581QrhmBO51byypZzgH4j2H+nRjZqn1ir1PDmr4lsTMgzHPvPPeHM7ONDfkU9L/54ms0n8jE2knF/Xx8evwWCP8Dm43m88ONpon0dWflwdLPzJsLtoaP+z/UB0iVJygCQyWTrgUmASAJCm5Mkib0pxSzelkJyYQ2h7rasmRvBkCDnRmv965QafjtTwPr4XE7mVGJmbER3LzvK5SpyyuQADcG/dZOvx7MruPfLI4C+7MPSmT2xveLT8p7kIuauvtw/YHSoK29PjqBOqeGlzWf4+aQ++D/YrwtPDAtotBfgZpMkibTiWnYkFrIjqYgzeVUMDHRi+eyoRt9ohNtPR/3f8wRyr3icB/S98gSZTDYfmA/g4+ODINyIhKxyFm9L4VhWOV2crPhkZk8mRLgb1vpLksTpvCo2xOfwy6kC6lRaAl06MW+wH4XVSrafK7zuZZdancSyAxm8v01fF+iRQX68MiHU8HxZrZInfjjBsczLK4vWzuuLu50l7/2RzJZT+ZgYyZjdvwuPD+244K/TSZzMrWBHYhE7korILNVPVPfwtuefY0N4eICvYZmqcPu6ZVO4JEnLgGWgby/Zwbcj3GZSCmv4YHsyu84X09nGnP/cE870aG9D2eVKuYqfT+azIT6X5MIaLE2NmdDdneEhLsRllLHmaDY63fVvuMoqreO5TacN+wZm9+9iSACSJPHj8Txe+PGM4fyFMUGMi3Dn6/0X2HIqHzMTIx4e4MtjQ/w7ZKOVUqPl6IUyticWsTOpiNJaJSZGMvoHODF3kB+jQ1079BuJ0PY6KgnkA95XPPZqOCYIf0luuZyPdqXy88l8Opmb8MKYrswZ6IuVmQmSJHHkQikb4nP541whKo2O7l52vDM5gr7+jnx3NJtFG06h1en7+j49ovXBX5Ikvo/N5p3fkw2tHPv5O/La3WEA5FXIGbv0IDUKDaDv8vXWpHC2nipg7NIDmJkYMXegH/OH+jepFNreahRq9qXoexLvSy6mRqnBysyY4V1dGB3myrCuLmLVz99YRyWBeCBIJpP5oQ/+M4BZHXQvwt9Aaa2Sz/em80NsDjIZzB/sz+NDA3CwNqO4RsHqI1lsjM8lq0yOrYUJM6O9mRbtTedO5ny5/wJv/JqIpiH4PzU8EB+n1m+4Kqis56XNZziYVkofP0dSi2owlslYOqMnAB/tTGXp7jTD+c+NCia9pJa5q+MxNzHm0cH+zBvsT2ebm7fDtqRGyc6kInYkFXIkvQyVVoeTtRnjItwZE+7KgABnMdRzh+iQJCBJkkYmkz0NbEe/RHSlJEmJHXEvwu2tRqHmm4OZfHMwg3q1lmlR3iwcGYSLjQX7U4tZfyyX3cnFaHUSffwcWTgyiLHh7lTXqxuVV763lydPDw+6ruAvSRI/n8zntV8S0eok/nNPOIkF1RzLLGf1nGgq5Wr6vrPbcH5XVxu8HS35cFcqFibGzBvsz7wh/jetvEJWaR07kgrZnljEiZwKJEn/jWR2/y6MCXejl49Dsz2Qhb+3DpsTkCTpd+D3jnp/4fam1Gj5ITaHz/amU16nYlyEG8+O6oq5iRHr4nLYmJBHYbUC505mPDrYj+lR3vh37kRxjYLF21L4IS4bTUN55adHNK6w2RqltUr+/fNZticWEdXFgSXTIjmbX8W6YznMHejHxoTcRq0iA106kVpcQ26FnMeGBDBvsB9O7Rz8JUniXH41O5IK2ZFYREpRDQBhHrYsiglmdJgrIW42TaqhCncWmSTd+nOuUVFRUkJCwrVPFP72tDqJLSfz+XBnKvmV9QwIcOLZUcEUVStZH5/DofRSAIYGd2ZGtDcjQlwxMzGiuEbB1/sz+D5WH/wn9/Tk6Yba+tdr27lC/v3zWWoUGp4bHcyjg/3Jr6hn/CcHqVFqmr3G2syY2QN8mTfYv13r6mi0Oo5lletX9CQWUlClwEgG0b6OjAlzY1Soq2jucgeRyWTHJUmKuto5t+zqIEG4kiRJ7DpfzAfbk0ktqiXC0455g/3Ir6xn/nfHKa9T4WFnwcKYIKZGeRs2cZXUKPl6/wW+j8tGpdExuacXz4y4seBfVa/mjV8S+elkPuGetqyb1oNgVxtUGh1zVh9rNgFYmxnz8EBfHh3kj0M7Bf96lZYDaSVsTyxkT3IxlXI15iZGDA7qzD9GBRPTzVUUdBNaJJKAcMs7llnO+9uSOZ5dgZutBSNCXKiqV/P6r0mYGMkYFerK9GhvBgd1Noxpl9bqg/93sfrgf09PT54ZEWSowHm9DqaV8OKPZyiuUbIgJohnRgQalptGvrHDsCLokk7mJswZ6Msjg/zapaBaRZ2K3cnF7Egs5EBaCQq1DlsLE0Z2c2V0mCtDgjuLTVxCq4i/JcIt6/zFahZvS2ZvSgkAZsZGVNWr2ZNcjL+zNf8aG8KUXl6NVtWU1ipZdiCD745mo9RouaeHfszf/wY7aclVGt79PZnvYrMJ6GzNT08MILKhh29RtaLRxC+AhakR8wf7M7cdgn9+ZT07E/UTu8eyytHqJNztLJge5c3oMDf6+DkaEpMgtJZIAsItJ6dMzoc7U9h6uoArp6xkMn2DlunR3vTxc2w0oVnWEPy/bQj+kxqC/19po3g8u5znNp4mu1zOI4P8eGFMVyxMjZEkiX9vOcfauJxG5y+MCWLuQD/srNpmTb0kSaQW6Us1bE8q5Fy+vkVlkEsnHh/qz5gwNyI87cTErvCXiCQg3DJKapR8uieNdcdyUGsvR/9u7rbM7OPNpB6eTTYtldUqWXYwg2+PZKPQaJkU6cHTI4IIdLnx4K/UaPlwZyrLD2TgYW/Junn96OfvBMDZvCru/uxQo/Mn9/Tk9YlhbbKhSqeTOJFTwY4k/cRuVkPNop4++lINo0Ndb/hbjSA0RyQBocNVK9QsP5DBikOZyFX6sfVO5iZM7OHBzGgfwj1tm3zaLa9TNXzyz6JerWVipAfP/MXgD3Auv4rnNp4mpaiGmX28+ff4UDqZm6DR6gj89x9Nzv/PPeE80K/LX3pPpUbLkQtl7EgsZGdSMaW1SkyNZfQPcGbeEH9GdXMVvXqFdiOSgNBhFGot38dm8/nedCoayjX37uLA9GhvJnR3b3Zis7xOxfKDGaw5og/+d3f3YEFMIIEuTXsBXA+NVseX+y6wdHcajtZmrHo4muEhLgC89VsSKw5lNrlmepT3DSeAGoWavSkl7EgsZF9KCbVKDdZmxgwLcWF0qCvDQ1waVRwVhPYikoDQIRRqLWOXHiSztA4HK1MeGeTHjGjvZhu7gH41zKXgL1drmdDdgwUjAls8/3qkF9fy3MZTnM6r4u5ID96aFIa9lRl7U4qZsyq+0bl7nhvKtK9jcbAy5fWJYdf1PsU1CnYlFbM9sZAjF0pRayWcO5lxd6Q7o0PdGBDo1KjNpCDcDCIJCB3CzNiIuyM9CHbtxKhQ1xaDX0Wdim8OZbD6sD74j49wZ0FMEMFtEPx1Dc3c39+WjKWZMZ/N6smE7h6cyKlgyhc7G53769ODCPOwZfbKY9Qq1ayd1xdLs2sH7MzSOv3EbmIhJ3MrkSTo4mTFnIH6ipw9RakGoYOJJCB0CCMjGc+OCm7x+Uq5im8OZrL6SBZ1Kg3jItxZ2EbBH/TVRl/48TSxGeWMCHHhvSkR5FbI6fP2LoprlIbzruwF8PnedA6ll/L+vREt3ockSZzNr2qowV9IapG+J3G4py3/GBnMmDA3gl07iRU9wi1DJAHhllIpV7HiUCarDmdRq9QYPvl3dWub4C9JEhsTcnnrt/MALL63O/6drXl63clGTV4ATr862rDcMz6rnCU7UpjUw4NpUd6NzlNrdcRnlrO9oevWxSoFxkYy+vg68trdPowKdW1VJzJB6AgiCQi3hCq5mhWHMlh1OIsapYZxEW4siAkixM22zd6juFrBP386y57kYvr5OzI92psfj+dxOL2s0Xmfz+rF+O7uhscVdSoWrDuJj6MVb0+OQCaTIVdpOJBayo7EQnYnF1NVry/VMCS4M8+N7kpMiEu7lYkQhLYkkoDQoarkalYczmTVoUxqlBrGhruxcGTbBn+A384U8PKWc9SrtIwNd6NCruIfG043OifS256Nj/VrND8hSRLPbzpNWa2KlQ9H88fZi+xIKuJgQ6kGO0tTYrq5MCbMjcFBzqJUg3DbEX9jhQ5RVa9m5aFMVh7OpEah4a4wffDv5t62wb+iTsWrvyTy6+kCAFxszPnjXGGT87Y+NdBQDuJKKw5lsju5GAtTIx5adQytTsLDzoIZ0T6MDnUlWpRqEG5zIgkIN1VVvZpVhzNZcUgf/MeEubIwJphQj7YN/gB7k4t5cfMZSq6Y6L1y0hfgwX5deH1iWLMrdDRaHR9sTwHAx9GKMWFujA51a3bzmiDcrkQSEG6KaoWaVYeyWHEog2qFhtGhriwcGUSYh12bv1etUsN/fktifXyu4ZiVmbFhN/IlB18cftXa+ibGRqyZ2wdXW4sbrj4qCLc6kQSEdlWtULP6cBbfHNQH/1GhriyMCSLcs+2DP0BsRhkzlsUaHjtYmeLjaMXpvCrDsTcmhjG7f5dWfZq/VDNIEP6uRBIQ2kXNpeB/KJOqejUju7myaGT7BX+FWsukzw4bWigCzBnoyw9xOYYE4OdszabH+9+0nr6CcDsQSUBoU02DvwsLY4KJ8Gqf4C9JEp/tSWfJzlTDsWdHBVNWq2TV4SzDseWzoxgV6tou9yAItzORBIQ2UaNQs+ZIFssP6oN/TIgLi0a2b/Dfdb6Yed9e7j19V5gb9/X24tE/HftgandsRDE2QWiWSALCX1Kr1DQE/wwq5WpGhLiwaGQQ3b2aLrdsC5IksS+lhKfWnmg00fu/BYN45/fzjRLAj4/3J8rXsV3uQxD+LkQSEG5Ic8F/YUxQs2vt24IkSexNKebDnamGDlsAS2f0oKxWxfhPLjd6eWyoP/8YGYyFqajIKQjXIpKAcF3qlBrWHM1i+YEMKuRqhnftzMKRwfRox+C/+3wxn+xJ48wVK3xiQlyY1deHF348Q3mdCtCvBFo3v1+b7zYWhL8zkQSEVqlTHKi6EAAAF1BJREFUavj2aDbLDlygQq5mWNfOLIwJoqePw/+3d+fxTZVZA8d/p0BlGbZSKGUpUFqW0gKFAi6ADqAiqCiOiqgzzqiMrws6r/O+wLjOMIr6jqPihog6riAKCgq4gBsgiIBAKWXphm0pUFronjTL8/6RgEVom7ZJ0zbn+/nwaXpvcnOehJ6T3HvPfXzyfCf3+T+37vRP/q1aNGPWxP7sO1LMrW/+suvnwckD+eMFffSyzErVkBYBVaXS8pPJP438knIu7NeZeydEM8yHyf+LPUeYv+4ASYcKCW7+yyUZxkSHcm5kJx79ZM+pZfERHZg/Lb7Kpi+lVOW0CKizKi2387Y7+eeVlDO2n+uT//Bevkn+Tqcr+T+37gDJOYX06tSa0VGh/PTzcZq1aMb1I3qSmF1w6jIOAE9fO4Spw7rrJRyUqgMtAuo0peV23tl8kFe+dSX/MdGh3DchmuG9fHOWjdNp+DzpMM+tO8Dew0X0CW3DA5MGsiUjny/3HGFQt3b0Dm3Df77POPWYyXHhPHrlIDq31aYvpepKi4ACoKzcNen7K9+lcqzYlfzvHR/ts1MsnU7DZ0mHme9O/pGhbXjm+iG0atGMBz/eTWGZnVF9Qth/pIikQ65jAsHNgnjpxmFM0KYvpbxGi0CAKyt38O4PB1nwrSv5j44K5d4J0YzwYfJfvTuH59elsO9IEZGd2/Ds9UO5sF9n5q7aw/Lt2YS0CaZ7x1b8UGGmr5vOjWDWxAHa9KWUl2kRCFC/JP80jhVbuSCqEy+N78fIPr5J/g6nYXViDvPXHeDA0WL6dm7Dc9OGcvngbmxKzWPS/PXkFFho2SKI/JLyU6d9RoS05unrhvisKCkV6LQIBBiLzcG7P/zMgm9TyS2ycn7fTrw4PZ5RPrpapsNp+HTXIZ7/KoWUo8VEd/kN82+IZ3JcOFa7g79/ksRbmw5WiM956vbdv43i7nFR2vSllA/5rAiIyKPA7UCue9HfjDGr3evmALcCDmCmMeZzX8WhfrElPZ+Zi3/icKGF8yI78fwN8T67VPLJ5D9/3QFSc0voF/YbXpgez6TYcIKChG0Hj3P/0h1k5JWe8dghPdrzxDWDvT7LmFLqTL7+JvCMMeZfFReISAwwDRgEdAPWikg/Y4zjbBtQdWeM4fWNGTy+OpmIkNYsvv1czuvrm+Rvdzj5xP3JPy23hP5hbXlx+jAui+1KUJBgtTt49osDvPJtKk5z5uO16Uup+uWP3UFTgCXGGCuQLiIpwEhgkx9iafJKrHZmLdvFp7tyuCQmjH9dN4R2Pji4anc4WbnTlfzTj5UwoGtbXr5xGJcOciV/gKRDBdy/dCd7Dxed8fjRUaE8fnUcEZ206Uup+uTrInC3iPwe2Arcb4w5DnQHNle4T5Z72WlEZAYwAyAiIsLHYTZNabnF3PHONlKOFvO/E/tzx9i+pxKyt9gdTj7ecYgXvjpARl4pA8PbseCmYVwS80vytzucLPg2lefWHcDmOP3jf7uWzXno8hh+N7yHNn0p5Qd1KgIishboepZVDwAvA3MB4/75NPAnT7dtjFkILARISEg4y44DVZXPkw5z/9KdBDcP4q0/jWJ0dKhXt293OPnop2xe+DqFg3mlxIS345Wbh3PxwLDTCk1qbjH3L93JjswTZ2xj8uBwHr1Cm76U8qc6FQFjzARP7icirwKfun/NBnpWWN3DvUx5gcNp+NcX+3j5m1SG9GjPSzcNp3uHVl7bvs3h5KPtruT/c34pg7q1Y+HNw7k4Juy0T/JOp+HNTRk8+dne0874AQhrdw7/vCpOZ/pSqgHw5dlB4caYHPevVwO73bdXAu+JyL9xHRiOBrb4Ko5Aklds5d4lO9iQcowbRkbwyBUxXju90uZwsnx7Fi98nUJmfhmx3dux6PcJjB/Y5YzdOFnHS/mfD3axKS3vjO3cOCqCWZcN8MlxCaVUzfnymMBTIjIU1+6gDODPAMaYJBFZCuwB7MBdemZQ3e3MPMF/vbONYyXlPHXNYK4b0bP6B3mg3O5k2fYsXvw6hazjZQzu0Z5HrxjEuAFnJn9jDB9szeIfn+6h2Go/bV1kaBvmTY3zWT+CUqp2fFYEjDE3V7HuMeAxXz13oFm85WceWZFE57bnsOyO870yr2+53cmH21zJP/tEGUN6tGfulFgu6t/5rAdwjxZZmLMskXV7j562vHmQ8OcLI7lnXLQ2fSnVAGnHcCNmsTl4ZEUS72/NZEx0KPOnxdOxTXCdtmm1O/hgaxYvf5NK9okyhvbswD+vjuWifmdP/gCrduXw4MeJHC+1nbY8rnt7nrxmMDHdtOlLqYZKi0AjlZlfyp3vbicxu4B7xkVx34R+dWqwstodLN2axctfp3CowEJ8RAcenxrH2OjQSpP/idJyHl6RxMqdh05b3rJFEPdf3J8/XtCb5s2CzvpYpVTDoEWgEfpufy4zl/yEw2lY9PuEOl1a2WJzsHRrJi9/k0pOgYXhvTryxDWDGVNF8gf4et9RZn24i6NF1tOWXxDVicevjqNXpza1jkkpVX+0CDQiTqfhpW9SePrL/fQPa8uCm4bTO7R2ydZic/D+j67kf7jQQkKvjvzf74ZwQVSnKpN/sdXOY6v2sHhL5mnL27VszoOXx3CtNn0p1ahoEWgkCsps3L90B2uTjzJlaDfmTY2jdXDN3z6LzcHiLa6riB4ptDKydwhPXzeE8/tWnfwBfkjL468f7iQzv+y05ZPjwnnkyhi6tG1Z43iUUv6lRaAR2Hu4kDve3kbW8TIevSKGP5zfu8afti02B++5LyF9tMjKyD4hPHP9UM6LrD75W2wO/vX5Pl7bmE6QCC2aCTaHIazdOcydEsslg87WNK6Uagy0CDRwK3ZkM2vZLtq1bMGSGefWeLrHk5PHvPJdGrlFVs6NDOG5afE1uorok5/t5Y2NGYS0CabEasdqdzJ9VASztelLqUZPi0ADVW538vjqZP7zfQYje4fwwo3xNdrd8uuZw+oyf8CVQ7rx3f5cUnNL6ONu+vLVPARKqfqlRaABOlJo4a53t7P14HFuHd2H2ZcNoIWHp1qWltt5Z/NBFn6XxrHicve0kcNqNW2kMYY1uw/z8IokjpeWc+dFfZk5Xpu+lGpKtAg0MFvS87nrve0UW+zMvyGeK4d08+hxpeV23t7kSv55JXWfMP5wgYWHVuzmyz1HiO3ejjf/NIJB3ereiayUali0CDQQFWf/6hXSmndvG0W/sLbVPq7EauetTQd5dX0a+SXljIkO5b4J0QzvVbvk73QalvyYybzVydicTv42aQB/uqCPNn0p1URpEWgASqx2Zi9P5JOdhzye/avYauetTRm8+l0ax0ttjO3XmXvHRzO8V8dax5GWW8yc5Yn8kJ7P+X07MW+qNn0p1dRpEfCzirN/zZo4gDsujKzylM0ii+3UJ/8TpTYu6t+ZmeOjGRZR++Rvczh5dX0az649QMvmQTx1zWCuTdCmL6UCgRYBP/rCPftXCw9m/yqy2PjPxgxe25jOiVIb4wZ0Yeb4aIb27FCnGBKzCpi1bBd7cgq5LLYrf79yEF3aadOXUoFCi4AfOJyGp7/Yx0sezP5VeDL5b0inoMzGeHfyH1LH5F9W7uDZtft5dX0aob85hwU3DWdirDZ9KRVotAjUs/yScmYu/qna2b8Kymy8sTGd1zekU2ixM2FgGPeOj/bKXAHfpxxjzkeJHMwr5YaRPZl92UDat9KmL6UCkRaBerQz8wR3vrud3GJrpbN/FZTZeH1DOq9vTKfIYufiGFfyj+1e9+RfUGrj8dXJvL81k96dWrP49nNr1DmslGp6tAjUk+pm/yootfHahjTe2JhBkdXOpYPCmDk+2mvn5q9JzOHhlUnkl5Rzx4V9uW+CNn0ppbQI+FzF2b/G9uvMc9cPPW32rxOl5by2IZ3/uJP/xEFdmTk+2muzcR0ptPDwit18nuRq+nrjlhFe+VahlGoatAj4UMXZv2aOi+LeCrN/HS8pZ9GGNN78/iDFVjuT4rpyz7hoBoZ7J/k7nYb3t2by+Opkyu1OZl82gNtGa9OXUup0WgR8pLLZv/JLylm0Po03v8+g1OZgUmw494yPYkBX783Dm36shDnLd7E5LZ/zIl1NX7WdfEYp1bRpEfCyymb/yiu28ur6dN7alEGZzcHkuHBmjo/26NIQnrI5nCxan86za/cT3DyIJ6bGcf2Intr0pZSqlBYBL3LN/rWTtclHTs3+VVbuYN6aZN7edJAym4PLB3dj5rgoor2Y/AF2Z7uavpIOFTJxUFf+MUWbvpRS1dMi4CW/nv3r8iHdeHbtAd7edBCL3cGVQ7pxz7goorp4N/mXlTt4dt1+Fq1PJ6RNMAtuGsbE2HCvPodSqunSIuAFK3ZkM3tZIm1bNueF6fFsO3icMU9+jdWd/O8eF01Ul994/Xm/Tz3GnOWupq9pI3oyZ5I2fSmlakaLQB3YHE4eW+Wa/SsytA2x3dtz3/s7KLc7uWpod+4aF0Xfzt5P/gVlNuatTmbJj5n06tSa924fxfl9K7/ukFJKVUaLQC0dLbRwp3v2L4Cf80vJyCvhqvju3P3bKCJ9kPwBPtudw0MrXE1ff74wkr9M6KdNX0qpWtMiUAsnZ//KLbIC0CxITiV/X52KebTQwsMrkvgs6TAx4dr0pZTyDi0CNVBx9i+H09AsSJga3527x0X5bPIVYwzv/5jJY+6mr1kTB3DbmD4ezzmslFJV0SLgIWMM9y/dyfKfsmkeJFyf0JO7fhtFRKfWPnvOjGMlzFmeyKa0PEb1CeGJawbTR5u+lFJepEXAQ1a7kz05hUwb4Ur+PUN8l/ztDieLNqTzzJf7CW4WxLypcVyf0JOgIG36Ukp5lxYBD7Vs0YzP7hvr8+ep2PR1SUwYc6+KJUybvpRSPlKnHcsicq2IJImIU0QSfrVujoikiMg+Ebm0wvKJ7mUpIjK7Ls/flFhsDp5Ys5cpL27kSKGVl28cxis3D9cCoJTyqbp+E9gNTAVeqbhQRGKAacAgoBuwVkT6uVe/CFwMZAE/ishKY8yeOsbRqG1KzWPO8l1k5JVyXUIPHpgUQ/vW2vSllPK9OhUBY0wycLYLlE0BlhhjrEC6iKQAI93rUowxae7HLXHfNyCLQEGZjSfWJLN4SyYRIa1597ZRXBClTV9Kqfrjq2MC3YHNFX7Pci8DyPzV8lFn24CIzABmAERERPggRP/6bPdhHl6xm2PFVmaMdTV9tQrWpi+lVP2qtgiIyFqg61lWPWCMWeH9kFyMMQuBhQAJCQnGV89T344WWXhkRRJrdh9mYHg7XvvDCK9MHq+UUrVRbREwxkyoxXazgYqzqPdwL6OK5U2aMYalWzN5bFUyFruT/7m0PzPGRmrTl1LKr3y1O2gl8J6I/BvXgeFoYAsgQLSI9MGV/KcB030UQ4NxMM/V9PV9ah4j+4TwxNQ4n11bSCmlaqJORUBErgaeBzoDq0RkhzHmUmNMkogsxXXA1w7cZYxxuB9zN/A50Ax43RiTVKcRNGB2h5PXNqTzzNr9tAgK4rGrY7lhRIQ2fSmlGgwxpuHvbk9ISDBbt271dxg1knSogNnLEknMLuDimDDmTomla3s9518pVX9EZJsxJqGq+2jHsJdZbA6eW3eAhd+l0bF1C16cPoxJcV11nl+lVIOkRcCLNqflMWd5IunHSrh2eA8emDyQDq2D/R2WUkpVSouAFxRabMxbvZfFW36mZ0gr3rl1FKOjtelLKdXwaRGooy+SDvPQit3kFlm5fUwf/nJxP1oH68uqlGocNFvVUm6RlUdXJrEqMYcBXduy8OYEhvTs4O+wlFKqRrQI1JAxhg+2ZfHYqmTKbA5t+lJKNWpaBGrg57xS/vZRIhtSjjGydwjzromjrzZ9KaUaMS0CHrA7nLyxMYOnv9xH86Ag/nlVLNNHatOXUqrx0yJQjeScQmYt28WurAImDOzC3KtiCW/fyt9hKaWUV2gRqITF5uD5rw7wyrdpdGjdghemxzM5LlybvpRSTYoWgbPYkp7P7OW7SMst4XfDe/DApIF0bKNNX0qppkeLQAVFFhtPrNnLuz/8TI+OrXj71pGMie7s77CUUspntAi4rd1zhAc/3s3RIgu3je7Df1+iTV9KqaYv4LNcbpGVRz9JYtUuV9PXgpuHM1SbvpRSASJgi4AxhmXbs5n76R7Kyh389ZJ+zBjbl+Dm2vSllAocAVkEMvNdTV/rDxxjRO+OzJs6mKgu2vSllAo8AVUEHE7DGxvTefqL/TQLEuZeFcuN2vSllApgAVMEknMKmb1sFzuzChg/wNX01a2DNn0ppQJbky8CFpuDF79O4eVvUmnfqgXP3xDP5YO16UsppaCJF4HM/FJueWMLqbklTB3WnYcmx2jTl1JKVdCki0BYu5b06tSGR64YxNh+2vSllFK/1qSLQHDzIF6/ZYS/w1BKqQZLT4pXSqkApkVAKaUCmBYBpZQKYFoElFIqgGkRUEqpAKZFQCmlApgWAaWUCmBaBJRSKoCJMcbfMVRLRHKBgz7afChwzEfbrm86loZJx9IwBcJYehljqrxcQqMoAr4kIluNMQn+jsMbdCwNk46lYdKxuOjuIKWUCmBaBJRSKoBpEYCF/g7Ai3QsDZOOpWHSsaDHBJRSKqDpNwGllApgWgSUUiqABVwREJFrRSRJRJwiUukpVSKSISKJIrJDRLbWZ4yeqsFYJorIPhFJEZHZ9Rmjp0QkRES+FJED7p8dK7mfw/2e7BCRlfUdZ1Wqe51F5BwRed+9/gcR6V3/UXrGg7HcIiK5Fd6L2/wRZ3VE5HUROSoiuytZLyIy3z3OXSIyrL5j9JQHY7lIRAoqvCcPe7RhY0xA/QMGAv2Bb4CEKu6XAYT6O966jgVoBqQCkUAwsBOI8XfsZ4nzKWC2+/Zs4MlK7lfs71hr+zoDdwIL3LenAe/7O+46jOUW4AV/x+rBWMYCw4DdlayfBKwBBDgX+MHfMddhLBcBn9Z0uwH3TcAYk2yM2efvOLzBw7GMBFKMMWnGmHJgCTDF99HV2BTgTfftN4Gr/BhLbXjyOlcc44fAeBGReozRU43l/0y1jDHfAflV3GUK8JZx2Qx0EJHw+omuZjwYS60EXBGoAQN8ISLbRGSGv4Opg+5AZoXfs9zLGpowY0yO+/ZhIKyS+7UUka0isllEGlKh8OR1PnUfY4wdKAA61Ut0NePp/5lr3LtQPhSRnvUTmtc1lr8PT50nIjtFZI2IDPLkAU1yonkRWQt0PcuqB4wxKzzczGhjTLaIdAG+FJG97kpcr7w0lgahqrFU/MUYY0SksnOXe7nfl0jgKxFJNMakejtWVa1PgMXGGKuI/BnXN5xxfo4p0G3H9fdRLCKTgI+B6Ooe1CSLgDFmghe2ke3+eVREPsL1Fbnei4AXxpINVPyU1sO9rN5VNRYROSIi4caYHPfX8aOVbOPk+5ImIt8A8bj2X/ubJ6/zyftkiUhzoD2QVz/h1Ui1YzHGVIx7Ea5jOo1Rg/n7qCtjTGGF26tF5CURCTXGVHmRPN0ddBYi0kZE2p68DVwCnPWIfCPwIxAtIn1EJBjXAckGdVaN20rgD+7bfwDO+JYjIh1F5Bz37VDgAmBPvUVYNU9e54pj/B3wlXEf0Wtgqh3Lr/abXwkk12N83rQS+L37LKFzgYIKuyUbFRHpevIYk4iMxJXfq/+Q4e8j3n44wn41rv1+VuAI8Ll7eTdgtft2JK4zInYCSbh2vfg99tqMxf37JGA/rk/MDXUsnYB1wAFgLRDiXp4ALHLfPh9IdL8vicCt/o77V2M443UG/gFc6b7dEvgASAG2AJH+jrkOY5nn/tvYCXwNDPB3zJWMYzGQA9jcfyu3AncAd7jXC/Cie5yJVHHGoL//eTCWuyu8J5uB8z3Zrl42QimlApjuDlJKqQCmRUAppQKYFgGllApgWgSUUiqAaRFQSqkApkVAKaUCmBYBpZQKYP8POhGvnsnSwoEAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.plot(X_test,y_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 只排列test即可\n",
    "s=sorted([(X_test[i][0], y_test[i]) for i in range(len(X_test))],key=lambda j:j[0])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[(-1.5714998476944846, -131.04367033539882),\n",
       " (-1.3859261882195588, -93.60922490234569),\n",
       " (-0.9058293853123284, -46.82647764830192),\n",
       " (-0.7748308990830076, -64.93070281473499),\n",
       " (-0.5636161626225747, -17.63342346132815),\n",
       " (-0.16158801768459224, -25.84828113880006),\n",
       " (-0.14399454133262268, 3.328948606065296),\n",
       " (0.31666736121885397, 54.55863304129922),\n",
       " (0.3705369823345305, 13.094438388527958),\n",
       " (0.42655243070263527, 26.730092304904865),\n",
       " (0.5224203020545581, 0.9068422926611959),\n",
       " (0.539490674855146, 35.78792578662397),\n",
       " (0.5409304592109262, 38.126123451757884),\n",
       " (0.6181208668574665, 53.52809607762425),\n",
       " (0.7751609192233712, 58.20603635525426),\n",
       " (1.2405376172537221, 53.718874121271746),\n",
       " (1.2995810607249982, 95.52025126381423),\n",
       " (1.3538115149528362, 75.94077855564103),\n",
       " (1.360471745925892, 109.9256877301055),\n",
       " (1.4086386638679793, 101.95945910307414)]"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "X_test=np.array([[j[0]] for j in s])\n",
    "y_test=np.array([j[1] for j in s])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<matplotlib.lines.Line2D at 0x11eb06908>]"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.plot(X_test,y_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 保存数据\n",
    "raw_data = (X_train, X_test, y_train, y_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pickle\n",
    "pkl_file = open('datas/linear_data.pkl', 'wb')\n",
    "pickle.dump(raw_data, pkl_file)\n",
    "pkl_file.close()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 115,
   "metadata": {},
   "outputs": [],
   "source": [
    "# import pickle\n",
    "# pkl_file = open('datas/linear_data.pkl', 'rb')\n",
    "# X_train, X_test, y_train, y_test = pickle.load(pkl_file)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br><br>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 线性回归"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [],
   "source": [
    "class Regression(object):\n",
    "    \n",
    "    \"\"\"\n",
    "        基础线性回归模型，使用输入的X和y进行参数回归\n",
    "        超参：\n",
    "        n_iterations:int 训练的步数，迭代多少次\n",
    "        learning_rate:float 学习率\n",
    "        \n",
    "        内部函数:\n",
    "        initialize_weights:初始化参数\n",
    "        fit:开始训练\n",
    "        predict:预测\n",
    "        \n",
    "        内部的数据:\n",
    "        n_iterations\n",
    "        learning_rate\n",
    "        regularization:正则化参数\n",
    "        regularization.grad:正则化的梯度函数\n",
    "    \"\"\"\n",
    "    \n",
    "    def __init__(self, n_iterations, learning_rate):\n",
    "        self.n_iterations=n_iterations\n",
    "        self.learning_rate=learning_rate\n",
    "        self.regularization=lambda x:0\n",
    "        self.regularization.grad=lambda x:0\n",
    "    \n",
    "    def initialize_weights(self, n_features):\n",
    "        \"\"\"初始化系数，输入是feature的个数，输出是一个随机初始化好的参数矩阵,[-1/sqrt(N),1/sqrt(N)]\"\"\"\n",
    "        # 实验得出经典算法，随机分布初始化系数\n",
    "        limit=1/math.sqrt(n_features)\n",
    "        self.w=np.random.uniform(-limit,limit,(n_features,))\n",
    "        #Uniform Distribution/Xavier/MSRA/Gaussian 高斯初始化\n",
    "    \n",
    "    def fit(self, X, y):\n",
    "        #插入偏置列1到X中\n",
    "        X = np.insert(X,0,1,axis=1)#给每一行的第0列增加一个1\n",
    "        self.training_errors = []#保存每一次步长的训练Loss\n",
    "        self.initialize_weights(n_features=X.shape[1])#初始化参数w\n",
    "        \n",
    "        #进行梯度下降迭代\n",
    "        for i in range(self.n_iterations):\n",
    "            y_pred=X.dot(self.w)#进行预测\n",
    "            #计算Loss\n",
    "            mse=np.mean(0.5*(y-y_pred)**2+self.regularization(self.w))\n",
    "            self.training_errors.append(mse)#将Loss加入到training_errors的数组中\n",
    "            #计算带有正则化项的梯度\n",
    "            g_w=-(y-y_pred).T.dot(X)/len(X)+self.regularization.grad(self.w)\n",
    "            #根据梯度下降的算法更新参数\n",
    "            self.w-=self.learning_rate*g_w\n",
    "            \n",
    "    def predict(self,X):\n",
    "        #通过输入X预测一个样本\n",
    "        X=np.insert(X,0,1,axis=1)\n",
    "        pred=X.dot(self.w)\n",
    "        return pred\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [],
   "source": [
    "model=Regression(n_iterations=1000, learning_rate=0.01)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [],
   "source": [
    "model.fit(X_train,y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [],
   "source": [
    "# model.training_errors"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 打印training_errors值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Text(0.5, 0, 'Steps')"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "training,=plt.plot(range(len(model.training_errors)), model.training_errors,label=\"Training Error\")\n",
    "plt.title(\"Linear Regression Training Error\")\n",
    "plt.ylabel(\"Train-Loss\")\n",
    "plt.xlabel(\"Steps\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([-2.42815335, 72.61965759])"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "model.w"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 评价模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [],
   "source": [
    "y_pred=model.predict(X_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [],
   "source": [
    "mse=mean_squared_error(y_pred,y_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "311.85783724440796"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "mse"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [],
   "source": [
    "import warnings\n",
    "warnings.filterwarnings(\"ignore\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<matplotlib.lines.Line2D at 0x11eb47550>]"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.plot(X_test,y_test,'k.')\n",
    "plt.plot(X_test,y_pred,'Y')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br><br>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 带有最小二乘法的线性回归"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [],
   "source": [
    "def lsm_function(X,y):\n",
    "    G=np.mat(np.insert(X,0,1,axis=1))\n",
    "    # squeeze 二维矩阵 -> 把它降成一维二元的矩阵np数组\n",
    "    # return np.asarray((G.T.dot(G)).I.dot(G.T).dot(y))\n",
    "    return np.squeeze(np.asarray((G.T.dot(G)).I.dot(G.T).dot(y)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([-2.42561025, 72.62091006])"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "lsm_function(X_train,y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([-2.42561025, 72.62091006])"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "lsm_function(X_train,y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [],
   "source": [
    "class LinearRegression(Regression):\n",
    "    \"\"\"带有最小二乘法的线性回归\n",
    "    参数:\n",
    "    -------------\n",
    "    n_iterations\n",
    "    \n",
    "    learning_rate\n",
    "    \n",
    "    gradient_descent:bool \n",
    "        决定是否使用梯度下降法，如果是True则使用梯度下降，False使用最小二乘\n",
    "    \"\"\"\n",
    "    def __init__(self, n_iterations=500, learning_rate=0.1, gradient_descent=True):\n",
    "        self.gradient_descent=gradient_descent\n",
    "        self.regularization=lambda x:0\n",
    "        self.regularization.grad=lambda x:0\n",
    "        super(LinearRegression,self).__init__(n_iterations=n_iterations,learning_rate=learning_rate)\n",
    "    \n",
    "    def fit(self,X,y):\n",
    "        if not self.gradient_descent:\n",
    "            self.w=lsm_function(X,y)\n",
    "        else:\n",
    "            super(LinearRegression,self).fit(X,y)\n",
    "    \n",
    "    def predict(self,X):\n",
    "        return super(LinearRegression,self).predict(X)\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [],
   "source": [
    "model=LinearRegression(n_iterations=1000, learning_rate=0.1, gradient_descent=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [],
   "source": [
    "model.fit(X_train,y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([-2.42561025, 72.62091006])"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "model.w"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [],
   "source": [
    "def test_and_draw(model):\n",
    "    y_pred=model.predict(X_test)\n",
    "    mse=mean_squared_error(y_test,y_pred)\n",
    "    print(\"方差:\",mse)\n",
    "    plt.plot(X_test,y_test,'k.')\n",
    "    plt.plot(X_test,y_pred,'Y')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "方差: 311.86402927010636\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "test_and_draw(model)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br><br>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "toc-hr-collapsed": false
   },
   "source": [
    "## 正则化回归\n",
    "\n",
    "正则化的 loss\n",
    "\n",
    "正则化的 grad梯度"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "7.0"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "w=[-3, 4]\n",
    "np.linalg.norm(w, ord=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "5.0"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.linalg.norm(w, ord=2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "toc-hr-collapsed": false
   },
   "source": [
    "### L2正则化参数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [],
   "source": [
    "class l1_regularization():\n",
    "    \"\"\"L1正则化类/函数\n",
    "    参数:\n",
    "    \n",
    "    alpha--L1正则化系数\n",
    "    \"\"\"\n",
    "    def __init__(self, alpha):\n",
    "        self.alpha=alpha\n",
    "    def __call__(self,w):\n",
    "        return self.alpha*np.linalg.norm(w,ord=1)\n",
    "    def grad(self,w):\n",
    "        #w>0->w`=1;w<0->w`=0;w==0->w`=0\n",
    "        return self.alpha*np.sign(w)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [],
   "source": [
    "l1=l1_regularization(alpha=0.01)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.07"
      ]
     },
     "execution_count": 44,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "l1([-3,4])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([-0.01,  0.01,  0.  ])"
      ]
     },
     "execution_count": 45,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "l1.grad([-3,4,0])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### L2正则化参数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {},
   "outputs": [],
   "source": [
    "class l2_regularization():\n",
    "    \"\"\"L2正则化参数\n",
    "    参数：\n",
    "    \n",
    "    alpha 正则化系数\n",
    "    \"\"\"\n",
    "    def __init__(self,alpha):\n",
    "        self.alpha=alpha\n",
    "    \n",
    "    def __call__(self,w):\n",
    "        return self.alpha*0.5*w.T.dot(w)\n",
    "    \n",
    "    def grad(self,w):\n",
    "        return self.alpha*w"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br><br>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### LassoLinearRegression"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [],
   "source": [
    "class LassoLinearRegression(Regression):\n",
    "    def __init__(self,alpha,n_iterations=1000,learning_rate=0.01):\n",
    "        self.regularization=l1_regularization(alpha=alpha)\n",
    "        super(LassoLinearRegression,self).__init__(n_iterations,learning_rate)\n",
    "        \n",
    "    def fit(self,X,y):\n",
    "        super(LassoLinearRegression,self).fit(X,y)\n",
    "    def predict(self,X):\n",
    "        return super(LassoLinearRegression,self).predict(X)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [],
   "source": [
    "model=LassoLinearRegression(alpha=120, n_iterations=1000,learning_rate=0.1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {},
   "outputs": [],
   "source": [
    "model.fit(X_train,y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([-2.42561025, 72.62091006])"
      ]
     },
     "execution_count": 50,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "model.w"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "方差: 311.8640292701059\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "test_and_draw(model)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br><br>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### RidgeLinearRegression"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {},
   "outputs": [],
   "source": [
    "class RidgeLinearRegression(Regression):\n",
    "    def __init__(self,alpha,n_iterations=1000,learning_rate=0.01):\n",
    "        self.regularization = l2_regularization(alpha=alpha)\n",
    "        super(RidgeLinearRegression, self).__init__(n_iterations, learning_rate)\n",
    "        \n",
    "    def fit(self,X,y):\n",
    "        super(RidgeLinearRegression, self).fit(X, y)\n",
    "    def predict(self,X):\n",
    "        return super(RidgeLinearRegression,self).predict(X)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {},
   "outputs": [],
   "source": [
    "model=RidgeLinearRegression(alpha=120,n_iterations=1000,learning_rate=0.1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {},
   "outputs": [],
   "source": [
    "model.fit(X_train,y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([-2.42561025, 72.62091006])"
      ]
     },
     "execution_count": 55,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "model.w"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "方差: 311.8640292701059\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "test_and_draw(model)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br><br>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### L1，L2调和的正则化\n",
    "\n",
    "在调和的正则化中，\n",
    "\n",
    "l1_ratio:调和时，L1正则化的值所占的百分比[0,1]\n",
    "\n",
    "\\_l2_ratio= 1 - l1_ratio(事实上在算法中也找不到l2_ratio)\n",
    "\n",
    "alpha:全局的整体的正则化权重\n",
    "\n",
    "Loss = mse + alpha * (l1\\_ratio * L1Loss + (1-l1\\_ratio) * L2Loss)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {},
   "outputs": [],
   "source": [
    "class l1_l2_regularization():\n",
    "    \"\"\"使用在ElasticNet中的正则化\"\"\"\n",
    "    \n",
    "    def __init__(self,alpha,l1_ratio=0.5):\n",
    "        self.alpha=alpha\n",
    "        self.l1_ratio=l1_ratio\n",
    "    \n",
    "    def __call__(self,w):\n",
    "        l1_loss=self.l1_ratio*np.linalg.norm(w,ord=1)\n",
    "        l2_loss=(1-self.l1_ratio)*0.5*w.T.dot(w) #np.linalg.norm(w,ord=2)**2\n",
    "        return self.alpha*(l1_loss+l2_loss)\n",
    "    def grad(self,w):\n",
    "        l1_grad=self.l1_ratio*np.sign(w)\n",
    "        l2_grad=(1-self.l1_ratio)*w\n",
    "        return self.alpha*(l1_grad+l2_grad)\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {},
   "outputs": [],
   "source": [
    "l1_l2=l1_l2_regularization(alpha=0.1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.9750000000000001"
      ]
     },
     "execution_count": 59,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "l1_l2(np.array([3,4]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0.2 , 0.25])"
      ]
     },
     "execution_count": 60,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "l1_l2.grad(np.array([3,4]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0.5, 0.5])"
      ]
     },
     "execution_count": 61,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "0.5*np.sign(np.array([3,4]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([1.5, 2. ])"
      ]
     },
     "execution_count": 62,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "0.5*np.array([3,4])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### ElasticNetLinearRegression"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {},
   "outputs": [],
   "source": [
    "class ElasticNetLinearRegression(Regression):\n",
    "    \"\"\"\n",
    "    ElasticNet线性回归算法\n",
    "    ----------------------\n",
    "    alpha:全局正则化参数\n",
    "    l1_ratio:L1正则化参数比例\n",
    "    n_iterations\n",
    "    learning_rate\n",
    "    \"\"\"\n",
    "    def __init__(self,alpha=0.05,l1_ratio=0.5,n_iterations=3000,learning_rate=0.01):\n",
    "        self.regularization=l1_l2_regularization(alpha=alpha,l1_ratio=l1_ratio)\n",
    "        super(ElasticNetLinearRegression,self).__init__(n_iterations,learning_rate)\n",
    "    def fit(self,X,y):\n",
    "        super(ElasticNetLinearRegression,self).fit(X,y)\n",
    "    def predict(self,X):\n",
    "        return super(ElasticNetLinearRegression,self).predict(X)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {},
   "outputs": [],
   "source": [
    "model=ElasticNetLinearRegression(l1_ratio=0.5,alpha=1.2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "metadata": {},
   "outputs": [],
   "source": [
    "model.fit(X_train,y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "方差: 311.86402927004417\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "test_and_draw(model)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.4rc1"
  },
  "toc-autonumbering": false
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
